home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / vla / stars.lzh / STARS.TXT < prev    next >
Text File  |  1993-03-16  |  9KB  |  230 lines

  1. ────────────────────────────────────────────────────────────────────────────
  2. ;
  3. ;     TITLE: Star field
  4. ;WRITTEN BY: DRAEDEN
  5. ;      DATE: 03/15/93
  6. ;
  7. ;     NOTES: 
  8. ;
  9. ;ASSOCIATED FILES:
  10. ;
  11. ;       STARGEN.BAS =>  Basic program that generates a set of 'randomized'
  12. ;                       numbers.  Creates STARRND.DW
  13. ;
  14. ;       STARS.ASM   =>  The asm file.
  15. ;
  16. ;       STARRND.DW  =>  File that contains a set of shuffled numbers order.
  17. ;                       Used to create 'random' star field.
  18. ;
  19. ────────────────────────────────────────────────────────────────────────────
  20.  
  21.     A star field is just a series of 3d point plotted onto a 2d plane (your
  22. screen).  The movement effect is achieved by simply decreasing the Z
  23. cordinate and redisplaying the results.  The formula for the 3d to 2d
  24. conversion is:
  25.  
  26. ──────────────── 
  27.     ScreenX = ScreenDist * Xpos / Zpos
  28.     ScreenY = ScreenDist * Ypos / Zpos
  29. ──────────────── 
  30.  
  31.     This should make perfect sense.  As the object gets futher away, (X,Y)
  32. cordinates converge to (0,0).  The screen dist is how far away the 'eye' is
  33. from the screen, or, as I like to think of it, the window.  Naturally, as you
  34. get closer to the window, your field of view is greatly enhanced (you can see
  35. more).  But, because we can't make the monitor bigger, we have to shrink the
  36. data that is being displayed.  And when we have a large screen distance, we
  37. should see less of the virtual world, and the objects should appear bigger.
  38. When this formula is translated into assembler, you would immediatly decide
  39. that 256 is the best screen distance.  Why?  Multiplying by 256 on the 386 is
  40. as simple as this:
  41.  
  42. ──────────────── 
  43. ;we want to multiply ax by 256 and put it into dx:ax to set up for division
  44.  
  45.     movsx   dx,ah   ;3 cycles
  46.     shl     ax,8    ;3 cycles -- total 6
  47.  
  48. ;or we could do it the 'normal way'...
  49.  
  50.     mov     dx,256  ;2 cycles, but we can have any screen distance
  51.     imul    dx      ;9-22 cycles on a 386, 13-26 on a 486
  52.                     ;a total of 11-28 cycles!
  53. ──────────────── 
  54.  
  55.     If you'll take note, the 6 cycle trick is AT LEAST 5 cycles faster than
  56. the imul.  Anyway... I bet you really don't care about a few cycles at this
  57. point, so I won't spend much more time on it... 
  58.     So, as you can see, the math part of it is easy..  the hard part is the
  59. what's left.  You need a routine that creates a star, presumably random, and
  60. another routine that displays all the stars and advances them.  Well, that's
  61. how I broke it into subroutines...
  62.  
  63.     For the routine that creates the star you need it to:
  64.  
  65.     1)  See if we already have enough stars going (is NUMSTARS > MAXSTARS ?)
  66.     2)  If there's room, scan for the first open slot... 
  67.     3)  Now that we've found where to put it, create a star by getting a set
  68.         of random numbers for the (X,Y) and setting the Z to the maximum.
  69.         Also select a color for the star.
  70.  
  71.     The display routine would need to:
  72.  
  73.     1)  Erase the old star.
  74.     2)  Calculate the screen X & Y positions for the new position.  Are they 
  75.         inside the screen boundries?  If not, 'kill' the star, otherwise 
  76.         display it.  The shade of the color to use must be calculated by 
  77.         using the Z cordinate. Color = BaseColor + Zpos / 256
  78.     3)  Decrease the Zpos.
  79.  
  80.     And the main routine would:
  81.  
  82.     1)  Call MakeStars
  83.     2)  Wait for verticle retrace
  84.     3)  Call DisplayStars
  85.     4)  Check for keypress, if there is one, handle it, if its not one we're
  86.         looking for then exit program.
  87.     5)  Loop to step 1
  88.  
  89.     To impliment this, we need to create an array of records which has enough
  90. room for MAXSTARS.  The record would contain the (X,Y,Z) cordinates, the
  91. OldDi and the base color for the star.  To create a star, it first checks to
  92. see if there is room.  If there is, then we scan through the array
  93. looking%wor an open slot.  If we don't find an empty space, then we don't
  94. create a star.  We create the star by grabbing a pair of (X,Y) cordinates
  95. from the list of 'random' numbers and set the Z to MAXZPOS.  Then, increase
  96. NUMSTARS and return.
  97.  
  98.     In displaying the star, we would like to only have to calculate DI once.
  99. So we save off a copy of DI in an array after we calculate it for the drawing
  100. so that erasing the dot is really quick.  Next we calculate the new DI for
  101. the dot.  This is done by using the formula mentioned above and this one: 
  102.  
  103. ──────────────── 
  104.  
  105.     DI = ScreenY * ScreenWidth + ScreenX
  106.  
  107. ──────────────── 
  108.  
  109.     When doing the math, care must be taken to make sure that:
  110.  
  111.         a) the Zpos is not zero and X*256/ZPOS is not greater than 32767.
  112.             will cause a DIVIDE BY ZERO or a DIVIDE OVERFLOW
  113.  
  114.         b) SY and SX do not go outside the border of the screen.
  115.  
  116.     If either of these conditions are broken, the star must be terminated and
  117. calculations for that star must be aborted.  Actually, Zpos = 0 is used to
  118. signify a nonactive star.  To terminate the star, you'd simply change its
  119. zpos to 0 and decrease NUMSTARS.
  120.  
  121.     To create the different shades, I used:
  122.  
  123. ────────────────
  124.  
  125.   Color = BaseColor + Zpos/256
  126.  
  127. ────────────────
  128.  
  129.     I used 256 as the number to divide by because that enables me to do no
  130. dividing at all- I just use AH, because AH = AX / 256 (AH is the upper 8 bits
  131. of AX). This relation suggests that the MAXZPOS shoul be 16*256 for 16
  132. shades.  So, the MAXZPOS = 4096.  The palette will have to be set up so that
  133. the shades go from light to black (lower # is lighter).  Simple enough. (I
  134. hope.)
  135.  
  136. ──────────────────────────────── 
  137.         RANDOM NUMBERS
  138. ──────────────────────────────── 
  139.  
  140.     Well, not truly random numbers, but random enough for a starfield.
  141.  
  142.     The problem:
  143.         There is no way on a PC to create truly random numbers with 
  144.         great speed.
  145.  
  146.     Solution:
  147.         Don't use truly random numbers.  Use a chart of non-repeating,
  148.         shuffled numbers that fall within your desired range.  That way
  149.         the stars will be evenly spread out and the creation of a new star
  150.         is incredably fast. ( A few MOV instructions) All you have to is grab
  151.         the number and increase the NEXTRANDOM pointer.  I chose to fill in
  152.         the array half with positive numbers, half with negative with a
  153.         minimum distance of 10 from 0.  I did this so that no stars will
  154.         'hit' the screen and just vanish.  That doesn't look too good.
  155.  
  156.     Here's the BASIC file that made my numbers for me...
  157.  
  158. ──────────────── 
  159.  
  160.  
  161.     NumStars = 400
  162.     dim     RndArray(NumStars)
  163.     randomize (timer)
  164.  
  165.     'fill the array with numbers from -Numstars/2 to -10
  166.     'and from 10 to Numstars/2
  167.  
  168.     i=10
  169.     for r = 0 to NumStars/2
  170.         RndArray(r)=i
  171.         i=i+1
  172.     next
  173.  
  174.     i=-10
  175.     for r = NumStars/2 to NumStars
  176.         RndArray(r)=i
  177.         i=i-1
  178.     next
  179.  
  180.     'randomly shuffle them..
  181.  
  182.     print "Total numbers: ";NumStars
  183.     print "Shuffling - Please wait... "
  184.  
  185.     for q = 1 to numstars/5
  186.         for r = 0 to NumStars
  187.             swnum1 = int(rnd*NumStars+.5)
  188.             swap RndArray(swnum1),RndArray(r)
  189.         next
  190.     next
  191.  
  192.     'write the numbers neatly to a file
  193.  
  194.     open "starrnd.dw" for output as 1
  195.     cc= 0          ' CC is my "Column Control"
  196.     print#1, "StarRnd dw ";:print#1, using"####";RndArray(0)
  197.     for r = 1 to NumStars
  198.  
  199.         IF cc=0 THEN   ' is this the first one on the line?
  200.             print#1, "dw ";:print#1, using"####" ;RndArray(r);
  201.         ELSE 
  202.             print#1, ",";:print#1, using"####"; RndArray(r);
  203.         END IF
  204.  
  205.         cc=cc+1:if cc= 10 then cc=0:print#1," "   'goto the next line
  206.     next
  207.     close #1
  208.  
  209. ──────────────── 
  210.  
  211.     This brings up another point.  Whenever you can write a program in a
  212. higher level language to create data for you, do it.  It sure beats typing
  213. then in by hand.  For instance, the palette was made using the REPT macro,
  214. the actual data is created by the compiler at compile time.  Doing it that 
  215. way happens to be a whole lot easier than typing in every byte.
  216.  
  217.     Last minute note: I rigged the plus and minus keys up so that they
  218. control the 'Warpspeed' can be from 0 - MaxWarp, which I set to 90 or 
  219. something like that.
  220.    
  221. ─────────────────────────────────────────────────────────────────────────────
  222.  
  223.    Well, that's it for now.  See INFO.VLA for information on contacting us.
  224.  
  225.    I would like some suggestions on what to write code for.  What would you
  226.    like to see done?  What code would you like to get your hands on?
  227.  
  228.    Send question, comments, suggestions to draeden@u.washington.edu or post
  229.     on Phantasm BBS.
  230.